package com.kun.video.config;

import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.StatusListenerConfigHelper;
import org.slf4j.LoggerFactory;

/**
 * @author gzc
 */
public class LogbackConfiguration  {

    public static void configure() {
        // 1. 获取 LoggerContext
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

        // 2. 设置上下文名称
        loggerContext.setName("nonWebContext");

        // 3. 配置状态监听器
        StatusListenerConfigHelper.addOnConsoleListenerInstance(loggerContext, new OnConsoleStatusListener());

        // 4. 配置控制台 Appender
        ConsoleAppender<ILoggingEvent> consoleAppender = createConsoleAppender(loggerContext);

        // 5. 配置文件 Appender
        RollingFileAppender<ILoggingEvent> fileAppender = createFileAppender(loggerContext);

        // 6. 配置根 Logger
        Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
        // 移除已有 Appender
        rootLogger.detachAndStopAllAppenders();
        rootLogger.setLevel(Level.INFO);
        rootLogger.addAppender(createAsyncAppender(loggerContext, consoleAppender));
        rootLogger.addAppender(createAsyncAppender(loggerContext, fileAppender));

        // 7. 启动所有组件
        consoleAppender.start();
        fileAppender.start();
    }

    private static AsyncAppender createAsyncAppender(LoggerContext context, Appender<ILoggingEvent> targetAppender) {
        AsyncAppender asyncAppender = new AsyncAppender();
        asyncAppender.setContext(context);
        asyncAppender.addAppender(targetAppender);
        asyncAppender.start();
        return asyncAppender;
    }

    private static ConsoleAppender<ILoggingEvent> createConsoleAppender(LoggerContext loggerContext) {
        // 控制台输出 Pattern
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
        encoder.setContext(loggerContext);
        encoder.start();

        // 控制台 Appender
        ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();
        appender.setContext(loggerContext);
        appender.setName("CONSOLE");
        appender.setEncoder(encoder);
        return appender;
    }

    private static RollingFileAppender<ILoggingEvent> createFileAppender(LoggerContext loggerContext) {
        // 文件输出 Pattern
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
        encoder.setContext(loggerContext);
        encoder.start();

        // 滚动策略配置
        SizeAndTimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new SizeAndTimeBasedRollingPolicy<>();
        rollingPolicy.setFileNamePattern("logs/app.%d{yyyy-MM-dd}.%i.log");
        rollingPolicy.setMaxHistory(30);
        rollingPolicy.setMaxFileSize(FileSize.valueOf("100MB"));
        // 需要关联父 Appender
        rollingPolicy.setParent(new FileAppender<>());
        rollingPolicy.setContext(loggerContext);
        rollingPolicy.start();

        // 文件 Appender
        RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
        appender.setContext(loggerContext);
        appender.setName("FILE");
        appender.setFile("logs/app.log");
        appender.setEncoder(encoder);
        appender.setRollingPolicy(rollingPolicy);
        return appender;
    }


}